import React, { useState, useEffect } from "react";
import * as THREE from "three";
import { GUI } from "three/addons/libs/lil-gui.module.min.js";
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
// import { TextureLoader } from 'three/addons/core/loaders/TextureLoader.js';
import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
import { OutputPass } from "three/addons/postprocessing/OutputPass.js";
import { returnLoadModel } from "@/script/utils/index";
import App from "@/script/App";
import { setDissolveShader } from "./config";

import styled from "styled-components";

function DissolveEffect() {
  let app: App;
  let shaders: any = [];
  let isDissolving = false;
  let gui: GUI;
  let clock: any,
    dt = 0;

  const FRAME_INTERVAL = 1 / 30;

  let params = {
    times: "repeat",
    edgeColor: 0xfa9200,
    edgeWidth: 0.1,
    dissolveSpeed: 0.01,
    dissolveProgress: 0,
    noiseTexture: new THREE.TextureLoader().load("/textures/noise.png"),
    edgeColorTexture: new THREE.TextureLoader().load("/textures/fire.jpg"),
    appear: appear,
    disappear: disappear,
  };

  let signedDissolveSpeed = params.dissolveSpeed;
  let lastRaf: any = -1;
  // 更新：根据按键进行移动
  const refThree = React.useRef<HTMLDivElement>(null!);
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 初始颜色绿色
  const cube = new THREE.Mesh(geometry, material);

  useEffect(() => {
    app = new App(refThree.current);
    app.addLight();
    app.addAxesHelper(5);
    app.orbitControls.target.set(2, 1, 1);
    const model = new THREE.Group();
    app.scene.add(model);

    clock = new THREE.Clock();

    app.scene.add(cube);

    returnLoadModel("Soldier", model, (model) => {
      model.traverse((object: THREE.Object3D) => {
        if (object instanceof THREE.Mesh) {
          object.castShadow = true;
          object.receiveShadow = true;
          object.frustumCulled = false;
          console.log("模型加载完毕", model);
          model.position.set(0, 0, 0);
          const material = object.material;

          material.transparent = true;

          material.onBeforeCompile = (shader: any) => {
            shaders.push(shader);
            setDissolveShader(shader, params);
          };
        }
      });
    });

    {
      gui = new GUI();
      gui.addColor(params, "edgeColor").onChange((v) => {
        for (let shader of shaders) {
          shader.uniforms.edgeColor = { value: new THREE.Color(v) };
        }
      });
      gui
        .add(params, "edgeWidth", 0.01, 1)
        .step(0.01)
        .onChange((v) => {
          for (let shader of shaders) {
            shader.uniforms.edgeWidth = { value: v };
          }
        });

      gui.add(params, "dissolveSpeed", 0.01, 0.1).step(0.01);
      gui.add(params, "appear");
      gui.add(params, "disappear");
    }

    animate();

    window.addEventListener("resize", onWindowResize);

    return () => {
      cancelAnimationFrame(lastRaf); // 清理渲染动画
      window.removeEventListener("resize", onWindowResize);
      app.renderer.dispose();
    };
  }, []);

  function animate() {
    lastRaf = requestAnimationFrame(animate);

    const time1 = Date.now() * 0.004; // 时间系数，控制闪烁速度
    const colorIntensity = (Math.sin(time1) + 1) / 2; // 让颜色强度在0到1之间波动

    // 改变材质颜色的RGB值，实现颜色变化的效果。这里以改变绿色（G）通道为例
    material.color.setRGB(0, colorIntensity, 0); // 只改变绿色通道，实现“呼吸”效果

    let time = clock.getDelta();

    dt += time;
    if (dt > FRAME_INTERVAL) {
      if (isDissolving) {
        for (let shader of shaders) {
          let { dissolveProgress, dissolveSpeed } = shader.uniforms;
          dissolveProgress.value += dissolveSpeed.value;
          if (dissolveProgress.value < 0) {
            isDissolving = false;
          }
          if (dissolveProgress.value > 1) {
            isDissolving = false;
          }
        }
      }

      dt %= FRAME_INTERVAL;
    }

    app.renderer.render(app.scene, app.camera);
    app.orbitControls.update();
  }

  function onWindowResize() {
    app.camera.aspect = window.innerWidth / window.innerHeight;
    app.camera.updateProjectionMatrix();
    app.renderer.setSize(window.innerWidth, window.innerHeight);
  }

  function appear() {
    console.log();

    if (isDissolving) return;
    isDissolving = true;
    signedDissolveSpeed = params.dissolveSpeed;

    for (let shader of shaders) {
      shader.uniforms.dissolveSpeed = { value: signedDissolveSpeed };
      shader.uniforms.dissolveProgress = { value: 0 };
    }
  }

  function disappear() {
    if (isDissolving) return;
    isDissolving = true;
    signedDissolveSpeed = -params.dissolveSpeed;

    for (let shader of shaders) {
      shader.uniforms.dissolveSpeed = { value: signedDissolveSpeed };
      shader.uniforms.dissolveProgress = { value: 1 };
    }
  }

  return (
    <div
      id="container"
      ref={refThree}
      style={{ width: "100vw", height: "100vh" }}
    ></div>
  );
}

export default DissolveEffect;
